home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Applications
/
NeuroSim 1.0
/
.cp
/
CNeuroSimPane.cp
< prev
next >
Wrap
Text File
|
1996-02-19
|
9KB
|
336 lines
// ===========================================================================
// CNeuroSimPane.cp ©1996 Timo Eloranta
// ===========================================================================
// This class takes care of displaying the picture of the neural net.
// Derived from the PowerPlant LView class.
#include "CNeuroSimPane.h"
#include "CNeuralNet.h"
#include "NS_Utils.h"
#include <UDrawingState.h>
#include <UGWorld.h>
#include <LWindow.h>
const Uint16 kIconSize = 16; // Icon size in pixels
const Uint16 kSquareSize = 21; // Grid square size in pixels
const RGBColor kBlackRGB = { 0, 0, 0 }; // black
const RGBColor kDarkRGB = { 0x0A05, 0x3E90, 0x05C1 }; // dark green
const RGBColor kBrightRGB = { 0x1F74, 0xFFFF, 0x088A }; // bright green
// ---------------------------------------------------------------------------
// • CNeuroSimPane
//
// Called by: CNeuroSimPane::CreateNeuroSimPaneStream
// ---------------------------------------------------------------------------
// Constructor. We call the base class with the LStream object reference
// and initialize some member attributes.
CNeuroSimPane::CNeuroSimPane(
LStream *inStream )
: LView( inStream )
{
Rect theFrame;
CalcLocalFrameRect( theFrame );
mGWorld = new LGWorld( theFrame, 8 );
if (! mGWorld )
::StopAlert( ALRT_Offscreen, NULL );
mNet = NULL;
mDrawingIsDirty = true;
mBackgroundIsDirty = true;
}
// ---------------------------------------------------------------------------
// • CreateNeuroSimPaneStream [static]
//
// Called by: CNeuroSimApp::InitNewNet (indirect call)
// ---------------------------------------------------------------------------
// Return a new NeuroSimPane object initialized using data from a Stream.
CNeuroSimPane*
CNeuroSimPane::CreateNeuroSimPaneStream(
LStream *inStream)
{
return ( new CNeuroSimPane( inStream ) );
}
// ---------------------------------------------------------------------------
// • ~CNeuroSimPane
// ---------------------------------------------------------------------------
// Destructor. Throw away the offscreen graphics world.
CNeuroSimPane::~CNeuroSimPane()
{
if ( mGWorld )
delete mGWorld;
}
// ---------------------------------------------------------------------------
// • SetNet
//
// Called by: CNeuroSimApp::InitNewNet
// ---------------------------------------------------------------------------
// Connect the given net to this pane, init member attributes and
// draw the net for the first time.
void
CNeuroSimPane::SetNet( CNeuralNet * inNet )
{
mNet = inNet;
mGridSize = mNet -> GetNetSize();
// Initializiation of mGridRect
CalcLocalFrameRect( mGridRect );
::InsetRect( &mGridRect, 1, 1 );
Int16 theGridWidth = mGridSize * kSquareSize;
Int16 theInset = (mGridRect.right - theGridWidth - 2) / 2;
::InsetRect( &mGridRect, theInset, theInset);
if ( theGridWidth % 2 ) {
mGridRect.right++;
mGridRect.bottom++;
}
// Initializiation of mOneOneRect
//
// We set the "one-one" rect to the [1,1] square of the matrix.
// The size of this rect is set according to kIconSize.
::SetRect( &mOneOneRect,
mGridRect.left + 1, // Left
mGridRect.top + 1, // Top
mGridRect.left + 1 + kIconSize, // Right
mGridRect.top + 1 + kIconSize); // Bottom
Int16 theOffset = (kSquareSize - kIconSize + 1) / 2;
::OffsetRect( &mOneOneRect, theOffset, theOffset);
// Initializiation of center points
//
// Center points are used when drawing connections between neurons.
// theOneOneXY is the point in the middle of the mOneOneRect. Only
// one value is needed, because the X and Y coordinates are equal.
Uint16 theOneOneXY = mGridRect.left + 1 + (kSquareSize / 2);
mNet -> SetCenterPoints( theOneOneXY, kSquareSize );
// Finally we draw the net for the first time
DrawTheNet();
}
// ---------------------------------------------------------------------------
// • InvalidateDrawing
//
// Called by: CNeuralNet::RequestDraw
// ---------------------------------------------------------------------------
// Force an immediate redraw of the net.
inline void
CNeuroSimPane::InvalidateDrawing()
{
mDrawingIsDirty = true;
LView::Draw( NULL );
}
// ---------------------------------------------------------------------------
// • DrawSelf
//
// Called by: LView::Draw
// ---------------------------------------------------------------------------
// Slam the net picture from the offscreen to the real screen...
void
CNeuroSimPane::DrawSelf()
{
Rect theFrame;
// If the net has changed and we still haven't drawn it to
// the offscreen, we better do it now...
if ( mDrawingIsDirty ) {
DrawTheNet();
FocusDraw();
}
CalcLocalFrameRect( theFrame );
StColorPenState::Normalize();
if ( mGWorld )
mGWorld -> CopyImage( GetMacPort(), theFrame );
}
// ---------------------------------------------------------------------------
// • ClickSelf
//
// Called by: LPane::Click
// ---------------------------------------------------------------------------
// Respond to clicks in this view
void
CNeuroSimPane::ClickSelf(
const SMouseDownEvent &inMouseDown)
{
Uint16 theCol, theRow;
Boolean theOptionDown; // Option-key held down while clicking ?
if ( PointToSquare( inMouseDown.whereLocal, theCol, theRow ) ) {
theOptionDown = (inMouseDown.macEvent.modifiers & optionKey) != 0;
CNeuronPtr theNeuron = mNet -> GetNeuron( theCol, theRow );
theNeuron -> DoClickAction( theOptionDown );
}
}
// ---------------------------------------------------------------------------
// • PointToSquare
//
// Called by: CNeuroSimPane::ClickSelf
// ---------------------------------------------------------------------------
// Check if the given point is inside our net matrix.
// If not, return FALSE. If it is, return TRUE and set the values of
// outCol and outRow to point to the correct column and row.
Boolean
CNeuroSimPane::PointToSquare(
const Point & inPoint,
Uint16 & outCol,
Uint16 & outRow )
{
if (! ::PtInRect( inPoint, &mGridRect ) )
return false;
else {
outCol = ((inPoint.h - mGridRect.left - 1) / kSquareSize) + 1;
if ( outCol > mGridSize )
outCol = mGridSize;
outRow = ((inPoint.v - mGridRect.top - 1) / kSquareSize) + 1;
if ( outRow > mGridSize )
outRow = mGridSize;
return true;
}
}
// ---------------------------------------------------------------------------
// • DrawTheNet
//
// Called by: CNeuroSimPane::SetNet
// CNeuroSimPane::DrawSelf
// ---------------------------------------------------------------------------
// Draw the net to our offscreen graphics world.
void
CNeuroSimPane::DrawTheNet()
{
if ( mGWorld ) {
FocusDraw();
StColorPenState theState;
mGWorld -> BeginDrawing(); // Here we go...
if ( mBackgroundIsDirty )
DrawBackground();
DrawConnections ();
DrawNeurons ();
DrawFrame();
mGWorld -> EndDrawing(); // Done...
Rect pRect = mGridRect;
LocalToPortPoint( topLeft( pRect ) );
LocalToPortPoint( botRight( pRect ) );
InvalPortRect( &pRect ); // Force update
mDrawingIsDirty = false; // No more "dirty"...
}
}
// ---------------------------------------------------------------------------
// • DrawBackground
//
// Called by: CNeuroSimPane::DrawTheNet
// ---------------------------------------------------------------------------
// Draw the background black and a dark green box around the entire grid.
void
CNeuroSimPane::DrawBackground()
{
Rect theFrame;
CalcLocalFrameRect( theFrame );
InsetRect( &theFrame, 1, 1); // A nice white frame...
::RGBBackColor( &kBlackRGB ); // Back color is black
::EraseRect( &theFrame);
::PenNormal();
::RGBForeColor( &kDarkRGB );
::FrameRect( &mGridRect); // Box around the entire grid
mBackgroundIsDirty = false; // We only do this once!
}
// ---------------------------------------------------------------------------
// • DrawConnections
//
// Called by: CNeuroSimPane::DrawTheNet
// ---------------------------------------------------------------------------
// Set the color to dark green and request the net to get all connections
// between neurons to be drawn...
void
CNeuroSimPane::DrawConnections()
{
::RGBForeColor( &kDarkRGB );
mNet -> DrawConnections();
}
// ---------------------------------------------------------------------------
// • DrawNeurons
//
// Called by: CNeuroSimPane::DrawTheNet
// ---------------------------------------------------------------------------
// Request the net to draw its neurons.
void
CNeuroSimPane::DrawNeurons()
{
mNet -> DrawNeurons( mOneOneRect, kSquareSize );
}
// ---------------------------------------------------------------------------
// • DrawFrame
//
// Called by: CNeuroSimPane::DrawTheNet
// ---------------------------------------------------------------------------
// Draw a bright frame around the matrix.
void
CNeuroSimPane::DrawFrame()
{
Rect theInnerFrame = mGridRect;
::InsetRect( &theInnerFrame, 1, 1 );
::RGBForeColor( &kBrightRGB );
::FrameRect( &theInnerFrame);
// Draw another bright box around the receptors (left side neurons)
theInnerFrame.right = theInnerFrame.left + kSquareSize;
::FrameRect( &theInnerFrame);
}